#include "wx/wxprec.h"
#include "wx/evtloop.h"
#include <gtk/gtk.h>

class wxEventLoopImpl {
  public:
    // ctor
    wxEventLoopImpl() { SetExitCode( 0 ); }

    // set/get the exit code
    void SetExitCode( int exitcode ) { m_exitcode = exitcode; }
    int GetExitCode() const { return m_exitcode; }

  private:
    // the exit code of the event loop
    int m_exitcode;
};

wxEventLoop::~wxEventLoop() {
  wxASSERT_MSG( !m_impl, _T( "should have been deleted in Run()" ) );
}

int wxEventLoop::Run() {
  // event loops are not recursive, you need to create another loop!
  wxCHECK_MSG( !IsRunning(), -1, _T( "can't reenter a message loop" ) );
  wxEventLoopActivator activate( this );
  m_impl = new wxEventLoopImpl;
  gtk_main();
  OnExit();
  int exitcode = m_impl->GetExitCode();
  delete m_impl;
  m_impl = NULL;
  return exitcode;
}

void wxEventLoop::Exit( int rc ) {
  wxCHECK_RET( IsRunning(), _T( "can't call Exit() if not running" ) );
  m_impl->SetExitCode( rc );
  gtk_main_quit();
}

// ----------------------------------------------------------------------------
// wxEventLoop message processing dispatching
// ----------------------------------------------------------------------------

bool wxEventLoop::Pending() const {
  if( wxTheApp ) {
    // We need to remove idle callbacks or gtk_events_pending will
    // never return false.
    wxTheApp->SuspendIdleCallback();
  }
  return gtk_events_pending();
}

bool wxEventLoop::Dispatch() {
  wxCHECK_MSG( IsRunning(), false, _T( "can't call Dispatch() if not running" ) );
  // gtk_main_iteration() returns TRUE only if gtk_main_quit() was called
  return !gtk_main_iteration();
}
